﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

using LowLevelGraphics;
using LowLevelGraphics.Filter;
using LowLevelGraphics.Types.Interval;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Matlab related function called imagesc
    /// </summary>
    public class imagesc : BaseImageFilter
    {
        protected byte[] m_aMap = null;
        protected IntInterval m_cLimit = new IntInterval(0, int.MaxValue / 2);
        protected int m_nArrayMaxIndex = -1;
        protected int m_nArrayMinIndex = int.MaxValue;

        /// <summary>
        /// constructor
        /// </summary>
        public imagesc(IntInterval _clim)
        {
            m_cLimit = _clim;
        }

        /// <summary>
        /// 
        /// </summary>
        public byte[] ColorMap
        {
            get { return m_aMap; }
            set
            {
                m_aMap = value;
                m_nArrayMaxIndex = m_aMap.Length - 1;
                m_nArrayMinIndex = 0;
            }
        }

        /// <summary>
        /// Used to create a deep copy
        /// </summary>
        /// <param name="_imagesc"></param>
        internal imagesc(imagesc _imagesc)
        {
            m_aMap = _imagesc.m_aMap;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {            
            unsafe
            {
                byte* Scan0 = (byte*)_bitmap.BitmapData.Scan0;
                byte* p = (byte*)(void*)Scan0;
                int stride = _bitmap.BitmapData.Stride;

                int nOffset = stride - _bitmap.Width * _bitmap.BytesPerPixelCount;
                int nWidth = _bitmap.Width * _bitmap.BytesPerPixelCount;

                int nHeight = _bitmap.Height;
                for (int y = 0; y < nHeight; ++y)
                {
                    for (int x = 0; x < nWidth; ++x)
                    {
                        if (p[0] < m_cLimit.Min)
                        {
                            p[0] = m_aMap[0];
                        }
                        if (p[0] > m_cLimit.Max)
                        {
                            p[0] = m_aMap[m_nArrayMaxIndex];
                        }
                        ++p;
                    }
                    p += nOffset;
                }
            }
            return _bitmap;
        }
        /// <summary>
        /// Clones this instance
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new imagesc(this);
        }
    }
}
